package com.infore.common.utils;

import com.infore.common.fw.DateUnit;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class DateUtils {

    /**
     * 年
     */
    public final static String DATE_YEAR="year";
    /**
     * 月
     */
    public final static String DATE_MONTH="month";
    /**
     * 日
     */
    public final static String DATE_DAY="day";
    /**
     * 季度
     */
    public final static String DATE_QUARTER="quarter";

    public static final String  DEFAULT_DATE_FORMATER = "yyyy-MM-dd HH:mm:ss";


    /**
     * 标准格式(yyyy-MM-dd)
     */
    public final static String DEF_FORMAT = "yyyy-MM-dd";

    /**
     * 日期格式yyyyMMdd
     */
    public final static String FORMAT_01 = "yyyyMMdd";

    /**
     * 日期格式yyyy/MM/dd
     */
    public final static String FORMAT_02 = "yyyy/MM/dd";

    /**
     * yyyy-MM
     */
    public final static String FORMAT_03 = "yyyy-MM";

    /**
     * yyyy-MM-dd HH:mm:ss
     */
    public static final String FORMAT_04 = "yyyy-MM-dd HH:mm:ss";

    /**
     * yyyy-MM-dd
     */
    public static final String FORMAT_05 = "yyyy-MM-dd";

    private final static int def_error = -1;

    private static String _format  = null;

    public static String DATEFIELD_YEAR = "year";

    public static String DATEFIELD_MONTH = "month";

    public static String DATEFIELD_DAY = "day";

    /**
     * 日历实例
     */
    private static Calendar def_ca = new GregorianCalendar();

    /**
     * 获取某年第一天日期
     *
     * @param year
     *            年份
     * @return Date
     */
    public static Date getCurrYearFirst(int year) {
        def_ca.clear();
        def_ca.set(Calendar.YEAR, year);
        return def_ca.getTime();
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year
     *            年份
     * @return Date
     */
    public static Date getCurrYearLast(int year) {
        def_ca.clear();
        def_ca.set(Calendar.YEAR, year);
        def_ca.roll(Calendar.DAY_OF_YEAR, -1);
        return def_ca.getTime();
    }

    /**
     * 获取某个月的最大天数
     *
     *            ，month月份
     * @return 该年该月的最大天数
     */
    public static int getDaysofMonth(int year, int month) {
        def_ca.clear();
        def_ca.set(Calendar.YEAR, year);
        def_ca.set(Calendar.MONTH, month - 1);
        return def_ca.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 在原来日期基础上增加天数
     *
     * @param date 指定日期
     * @param days 增加的天数
     * @return 增加后的日期
     */
    public static Date addDays(Date date, int days) {
        def_ca.setTime(date);
        def_ca.add(Calendar.DATE, days);
        return def_ca.getTime();
    }

    /**
     * 设置自定义的日期格式
     *
     */
    private static void setFormat(String format) {
        _format = format;
    }

    public static synchronized String formatDate(Date date) {
        DateFormat def_df = new SimpleDateFormat(DEF_FORMAT);
        if (date == null)
            throw new IllegalArgumentException("The date must not be null");
        return def_df.format(date);
    }

    /**
     * 将日期转换成对应格式的字符串(如何_format为空则按标准格式转换) 如果日期为空则将抛出异常
     *
     * @param date
     * @param format
     * @return
     */
    public static synchronized String formatDate(Date date, String format) {
        if (date == null)
            throw new IllegalArgumentException("The date must not be null");
        if (StringUtils.isBlank(format))
            throw new IllegalArgumentException("The format must not be null");
        setFormat(format);
        DateFormat df = new SimpleDateFormat(_format);
        return df.format(date);
    }

    /**
     * 增加year,month,day等等
     *
     * @param date
     * @param field
     * @param amount
     * @return
     */
    public static synchronized Date addDate(String date, int field, int amount) {
        DateFormat def_df = new SimpleDateFormat(DEF_FORMAT);
        if (StringUtils.isBlank(date)) {
            throw new IllegalArgumentException("The date must not be null");
        }
        try {
            def_ca.setTime(def_df.parse(date));
        } catch (ParseException e) {
        }
        def_ca.add(field, amount);
        return def_ca.getTime();
    }

    public static synchronized Date addDoubleDate(String date, int field1, int amount1, int field2, int amount2) {
        DateFormat def_df = new SimpleDateFormat(DEF_FORMAT);
        if (StringUtils.isBlank(date)) {
            throw new IllegalArgumentException("The date must not be null");
        }
        try {
            def_ca.setTime(def_df.parse(date));
        } catch (ParseException e) {
        }
        def_ca.add(field1, amount1);
        def_ca.add(field2, amount2);
        return def_ca.getTime();
    }

    /**
     * 增加年份
     *
     * @param year
     * @param count
     * @return
     */
    public static synchronized String addYears(String year, int count) {
        if (StringUtils.isBlank(year))
            throw new IllegalArgumentException("The year must not be null");
        def_ca.clear();
        def_ca.set(Calendar.YEAR, Integer.parseInt(year));
        def_ca.add(Calendar.YEAR, count);
        return def_ca.get(Calendar.YEAR) + "";
    }

    /**
     * 将Timestamp拆分成year month day存在map中
     *
     * @param date
     * @return
     */
    public static Map<Object, Object> getYearMonthDaytoMap(Timestamp date) {
        if (date == null) {
            return getYearMonthDaytoMap();
        } else {
            return getYearMonthDaytoMap(new Date(date.getTime()));
        }
    }

    /**
     * 将String类型的日期格式(yyyy-MM-dd)分成年、月、日封装在map中
     *
     * @param date
     * @return
     */
    public static synchronized Map<Object, Object> getYearMonthDaytoMap(String date) {
        DateFormat def_df = new SimpleDateFormat(DEF_FORMAT);
        Map<Object, Object> map = new HashMap<Object, Object>();
        if (StringUtils.isNotBlank(date)) {
            try {
                def_ca.setTime(def_df.parse(date));
                map.put("year", def_ca.get(Calendar.YEAR));
                map.put("month", def_ca.get(Calendar.MONTH) + 1);
                map.put("day", def_ca.get(Calendar.DAY_OF_MONTH));
            } catch (ParseException e) {
                return getYearMonthDaytoMap();
            }
        } else {
            return getYearMonthDaytoMap();
        }
        return map;
    }

    /**
     * 将String类型的日期格式分成年月日封装在map中
     *
     * @param date
     * @param format
     * @return
     */
    public static synchronized Map<Object, Object> getYearMonthDaytoMap(String date, String format) {
        Map<Object, Object> map = new HashMap<Object, Object>();
        if (StringUtils.isBlank(format))
            throw new IllegalArgumentException("The format must not be null");
        setFormat(format);
        DateFormat df = new SimpleDateFormat(_format);
        if (StringUtils.isNotBlank(date)) {
            try {
                def_ca.setTime(df.parse(date));
                map.put("year", def_ca.get(Calendar.YEAR));
                map.put("month", def_ca.get(Calendar.MONTH) + 1);
                map.put("day", def_ca.get(Calendar.DAY_OF_MONTH));
            } catch (ParseException e) {
                return getYearMonthDaytoMap();
            }
        } else {
            return getYearMonthDaytoMap();
        }
        return map;
    }

    /**
     * 将空值赋值的年月日给map
     *
     * @return
     */
    public static Map<Object, Object> getYearMonthDaytoMap() {
        Map<Object, Object> map = new HashMap<Object, Object>();
        map.put("year", "");
        map.put("month", "");
        map.put("day", "");
        return map;
    }

    /**
     * 将Date类型的日期格式分成年月日封装在map中
     *
     * @return
     */
    public static Map<Object, Object> getYearMonthDaytoMap(Date date) {
        Map<Object, Object> map = new HashMap<Object, Object>();
        if (date != null) {
            def_ca.setTime(date);
            map.put("year", def_ca.get(Calendar.YEAR));
            map.put("month", def_ca.get(Calendar.MONTH) + 1);
            map.put("day", def_ca.get(Calendar.DAY_OF_MONTH));
        } else {
            return getYearMonthDaytoMap();
        }
        return map;
    }

    /**
     * 将日期格式成年月封装在map中（）
     *
     * @param date
     * @param format
     * @return
     */
    public static synchronized Map<Object, Object> getYearMonthtoMap(String date, String format) {
        Map<Object, Object> map = new HashMap<Object, Object>();
        if (StringUtils.isBlank(format))
            throw new IllegalArgumentException("The format must not be null");
        setFormat(format);
        DateFormat df = new SimpleDateFormat(_format);
        if (StringUtils.isNotBlank(date)) {
            try {
                def_ca.setTime(df.parse(date));
                map.put("year", def_ca.get(Calendar.YEAR));
                map.put("month", def_ca.get(Calendar.MONTH) + 1);
            } catch (ParseException e) {
                map.put("year", "");
                map.put("month", "");
            }
        } else {
            map.put("year", "");
            map.put("month", "");
        }
        return map;
    }

    public static int getAge(Date dateOfBirth, Date nowDate) {
        def_ca.setTime(nowDate);
        int now_year = def_ca.get(Calendar.YEAR);
        def_ca.setTime(dateOfBirth);
        int age = now_year - def_ca.get(Calendar.YEAR);
        return age >= 0 ? age : def_error;
    }

    public static synchronized Date dateAdd(String dateString, String field, int amount) {
        DateFormat df = new SimpleDateFormat(DEF_FORMAT);
        Date date = new Date();
        try {
            date = df.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateAdd(date, field, amount);
    }

    public static synchronized Date dateAdd(Date date, String field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (field.equals(DATEFIELD_YEAR)) {
            calendar.add(Calendar.YEAR, amount);
        } else if (field.equals(DATEFIELD_MONTH)) {
            calendar.add(Calendar.MONTH, amount);
        } else if (field.equals(DATEFIELD_DAY)) {
            calendar.add(Calendar.DAY_OF_YEAR, amount);
        }
        return calendar.getTime();
    }

    /**
     * 返回传入日期的月份的最后一天 com.infore.qyws.jkhd.dao.impl 2012-8-8
     */
    public static Date getMonthLastDay(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String month = date.substring(date.length() - 2, date.length());
        int year = getYear(date);
        int lastDay = 31;

        ArrayList<String> littleMonth = new ArrayList<String>();
        littleMonth.add("04");
        littleMonth.add("06");
        littleMonth.add("09");
        littleMonth.add("11");
        if (month == "02") {
            if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
                lastDay -= 2;
            } else {
                lastDay -= 3;
            }
        } else if (littleMonth.contains(month)) {
            lastDay -= 1;
        }
        try {
            return sdf.parse(year + month + lastDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回传入日期的月份的第一天 com.infore.qyws.jkhd.dao.impl 2012-8-8
     */
    public static synchronized Date getMonthFirstDay(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            return sdf.parse(date + "01");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回传入日期的年份 com.infore.qyws.jkhd.dao.impl 2012-8-8
     */
    public static int getYear(String date) {
        return Integer.parseInt(date.substring(0, date.length() - 2));
    }

    /**
     * 返回传入日期的年份的第一天 com.infore.qyws.jkhd.dao.impl 2012-8-8
     */
    public static synchronized Date getYearFirstDay(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            return sdf.parse(getYear(date) + "0101");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回传入日期的年份的最后一天 com.infore.qyws.jkhd.dao.impl 2012-8-8
     */
    public static synchronized Date getYearLastDay(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            return sdf.parse(getYear(date) + "1231");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 根据出生日期返回年龄
     * @param dateOfBirth 出生日期（格式必须是yyyy-MM-dd）
     * @param nowDate 当前日期（格式必须是yyyy-MM-dd）
     * @return
     */
    public static synchronized int getAge(String dateOfBirth, String nowDate){
        DateFormat def_df = new SimpleDateFormat(DEF_FORMAT);
        try {
            def_ca.setTime(def_df.parse(nowDate));
        } catch (ParseException e1) {
            return def_error;
        }
        int now_year = def_ca.get(Calendar.YEAR);
        try {
            def_ca.setTime(def_df.parse(dateOfBirth));
        } catch (ParseException e) {
            return def_error;
        }
        int age = now_year - def_ca.get(Calendar.YEAR);
        return age>=0 ? age : def_error;
    }


    /**
     * 根据出生日期返回年龄(目前只支持年数，月数，天数)
     * @param nowDate 当前日期（格式必须是yyyy-MM-dd）
     * @param field 区域(如果是天数，则必须用Calendar.DAY_OF_YEAR)
     * @return
     */
    public static int getAge(Date birthday, Date nowDate, int field) {
        if(birthday==null||nowDate==null){
            return def_error;
        }
        def_ca.setTime(birthday);
        int _birthday = def_ca.get(field);
        def_ca.setTime(nowDate);
        int result = def_ca.get(field) - _birthday;
        return result>=0 ? result : def_error;
    }

    public static int getHours(Date birthday, Date nowDate){
        if(birthday==null&&nowDate==null){
            return def_error;
        }
        def_ca.setTime(nowDate);
        long now = def_ca.getTimeInMillis();
        def_ca.setTime(birthday);
        return (int)((now - def_ca.getTimeInMillis())/3600000);
    }

    public static int getMinutes(Date birthday, Date nowDate) {
        if(birthday==null&&nowDate==null){
            return def_error;
        }
        def_ca.setTime(nowDate);
        long now = def_ca.getTimeInMillis();
        def_ca.setTime(birthday);
        return (int)(((now - def_ca.getTimeInMillis())%3600000)/60000);
    }

    /**
     * 将日期转换为当日开始的日期
     */
    public static Date getBeginDateOfDay(final Date date) {
        try {
            return converToDate(formatDate(date, DEF_FORMAT) + " 00:00:00", FORMAT_04);
        } catch (ParseException e) {
            throw new RuntimeException(e.getMessage(), e); // Will Never happen
        }
    }

    /**
     * 将输入的日期字符串转换为当日开始日期
     * @throws ParseException
     */
    public static Date getBeginDateOfDay(final String date, final String pattern) throws ParseException {
        return converToDate(date + " 00:00:00", pattern);
    }

    /**
     * 将输入日期转换为当日结束日期
     */
    public static Date getEndDateOfDay(final Date date) {
        try {
            return converToDate(formatDate(date, DEF_FORMAT) + " 23:59:59", FORMAT_04);
        } catch (ParseException e) {
            throw new RuntimeException(e.getMessage(), e); // Will Never happen
        }
    }

    /**
     * 将输入的日期字符串转换为当日结束日期
     * @throws ParseException
     */
    public static Date getEndDateOfDay(final String date, final String pattern) throws ParseException {
        try {
            return DateUtils.getEndDateOfDay(converToDate(date, pattern));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        //return converToDate(date + " 23:59:59", pattern);
    }

    /**
     * 将字符串按照指定格式转换为日期
     * @param source 字符串
     * @param pattern 指定格式
     * @return 日期
     * @throws ParseException
     */
    public static synchronized Date converToDate(final String source, final String pattern) throws ParseException {
        return new SimpleDateFormat(pattern).parse(source);
    }
    //获取指定时间，指定格式 的串
    public static synchronized String getNowTime(Date date,String dateformat){
        SimpleDateFormat   dateFormat   =   new   SimpleDateFormat(dateformat);//可以方便地修改日期格式
        String  t  = dateFormat.format(date);
        return t;
    }
    //获取指定时间,指定格式的Date类型
    public static synchronized Date getNowDate(String date,String dateformat) throws Exception{
        SimpleDateFormat   dateFormat   =   new   SimpleDateFormat(dateformat);
        Date time = dateFormat.parse(date);
        return time;
    }

    /**
     * 获取当天时间
     * @return
     */
    public static Date getToDay(){
        def_ca.clear();
        def_ca.setTime(new Date());
        def_ca.set(Calendar.HOUR_OF_DAY, 0);
        def_ca.set(Calendar.MINUTE, 0);
        def_ca.set(Calendar.SECOND, 0);
        return def_ca.getTime();
    }
    /**
     * 格式化字符串格式的日期，并在日期上各域添加或减少，如何格式不匹配将返回空
     * @param date	日期
     * @param field	日期域
     * @param amount 数量
     * @param formatPattern 转换格式
     * @return
     */
    public static synchronized Date addDate(String date, int field, int amount, String formatPattern){
        DateFormat   def   =   new   SimpleDateFormat(formatPattern);
        try {
            def_ca.setTime(def.parse(date));
            def_ca.add(field, amount);
            return def_ca.getTime();
        } catch (ParseException e) {
            return null;
        }

    }

    public static synchronized Date parseDate(String date, String formatPattern){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatPattern);
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(sFormat.parse(date));
            return def_ca.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getPreviousDate(Date date) {
        Calendar cl = Calendar.getInstance();
        cl.setTime(date);
        cl.add(Calendar.DATE, -1);
        SimpleDateFormat sdf = new SimpleDateFormat(DEF_FORMAT);
        return sdf.format(cl.getTime());
    }

    public static String getPreviousMonth(Date date) {
        Calendar cl = Calendar.getInstance();
        cl.setTime(date);
        cl.add(Calendar.MONTH, -1);
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_03);
        return sdf.format(cl.getTime());
    }


    /**
     * <根据年和周，得到该周的最后一天》
     * <功能详细描述>
     * @param year
     * @param week
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String getEndDateByYearAndWeek(int year,int week,String formatString){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatString);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.set(Calendar.WEEK_OF_YEAR,week);
        cal.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
        Date endDate = cal.getTime();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, Calendar.DECEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        if(endDate.after(calendar.getTime())){
            return sFormat.format(calendar.getTime());
        }
        return sFormat.format(endDate);
    }

    /**
     * <根据年和周，得到该周的最后一天》
     * <这里要把拿到的日期和当前日期比较，如果大于当前日期则取当前日期>
     * @param year
     * @param week
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String getEndDateByYearAndWeek(int year,int week,String formatString,Boolean compareCurrentDate){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatString);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.set(Calendar.WEEK_OF_YEAR,week);
        cal.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
        Date endDate = cal.getTime();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, Calendar.DECEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        if(endDate.after(calendar.getTime())){
            endDate = calendar.getTime();
        }
        if(compareCurrentDate){
            if(endDate.after(new Date())){
                endDate = new Date();
            }
        }
        return sFormat.format(endDate);
    }

    /**
     * <根据年和月，得到该月的最后一天>
     * <这里只转换，不考虑和当前时间的比较>
     * @param year
     * @param month
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String getEndDateByYearAndMonth(int year,int month,String formatString){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatString);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.set(Calendar.MONTH,month);
        cal.set(Calendar.DAY_OF_MONTH,0);
        return sFormat.format(cal.getTime());
    }

    /**
     * <根据年和月，得到该月的最后一天>
     * <这里不只是转换，如果转换过来的日期比当前日期要大，则返回当期日期>
     * @param year
     * @param month
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String getEndDateByYearAndMonth(int year,int month,String formatString,Boolean compareCurrentDate){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatString);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.set(Calendar.MONTH,month);
        cal.set(Calendar.DAY_OF_MONTH,0);
        Date endDate = cal.getTime();
        if(compareCurrentDate){
            if(endDate.after(new Date())){
                return sFormat.format(new Date());
            }
        }
        return sFormat.format(cal.getTime());
    }


    /**
     * @描述：<根据年和周，得到该周的第一天>
     * @param year
     * @param week
     * @param formatString
     * @return
     * @创建人：JW
     * @创建时间：2014-1-20 上午09:29:49
     * @修改人：
     * @修改时间：
     * @修改备注：
     * @version 1.0
     *
     */
    public static String getStartDateByYearAndWeek(int year,int week,String formatString){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatString);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.set(Calendar.WEEK_OF_YEAR,week);
        cal.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);
        Date startDate = cal.getTime();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        if(startDate.before(calendar.getTime())){
            return sFormat.format(calendar.getTime());
        }
        return sFormat.format(startDate);
    }

    /**
     * @描述：<根据年和月，得到该月的第一天>
     * @param year
     * @param month
     * @param formatString
     * @return
     * @创建人：JW
     * @创建时间：2014-1-20 上午09:29:53
     * @修改人：
     * @修改时间：
     * @修改备注：
     * @version 1.0
     *
     */
    public static String getStartDateByYearAndMonth(int year,int month,String formatString){
        SimpleDateFormat sFormat = new SimpleDateFormat(formatString);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.set(Calendar.MONTH,month-1);
        cal.set(Calendar.DAY_OF_MONTH,1);
        return sFormat.format(cal.getTime());
    }

    public static int getBetweenDays(String t1,String t2) throws ParseException{
        DateFormat format = new SimpleDateFormat("yyyyMMdd");
        int betweenDays = 0;
        Date d1 = format.parse(t1);
        Date d2 = format.parse(t2);
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        // 保证第二个时间一定大于第一个时间
        if(c1.after(c2)){
            //c1 = c2;
            c2.setTime(d1);
            c1.setTime(d2);
        }
        int betweenYears = c2.get(Calendar.YEAR)-c1.get(Calendar.YEAR);
        betweenDays = c2.get(Calendar.DAY_OF_YEAR)-c1.get(Calendar.DAY_OF_YEAR);
        for(int i=0;i<betweenYears;i++){
            c1.set(Calendar.YEAR,(c1.get(Calendar.YEAR)+1));
            betweenDays += c1.getMaximum(Calendar.DAY_OF_YEAR);
        }
        return betweenDays;
    }

    public static Map getStartAndEndDateFromDateType(String startDate,String endDate,String dateType){
        Map dateMap =  new LinkedHashMap();
        String start = "";
        String end = "";
        if("day".equals(dateType)){
            start = startDate;
            end = endDate;
        }else if("week".equals(dateType)){
            start = getStartDateByYearAndWeek(Integer.valueOf(startDate.substring(0, 4)),Integer.valueOf(startDate.substring(5, 7)), "yyyyMMdd");
            end = getStartDateByYearAndWeek(Integer.valueOf(endDate.substring(0, 4)),Integer.valueOf(endDate.substring(5, 7)), "yyyyMMdd");
        }else if("month".equals(dateType)){
            start = getStartDateByYearAndMonth(Integer.valueOf(startDate.substring(0, 4)),Integer.valueOf(startDate.substring(4, 6)), "yyyyMMdd");
            end = getEndDateByYearAndMonth(Integer.valueOf(endDate.substring(0, 4)),Integer.valueOf(endDate.substring(4, 6)), "yyyyMMdd");
        }else if("season".equals(dateType)){
            start = getStartDateByYearAndWeek(Integer.valueOf(startDate.substring(0, 4)),Integer.valueOf(startDate.substring(5, 7)), "yyyyMMdd");
            end = getStartDateByYearAndWeek(Integer.valueOf(endDate.substring(0, 4)),Integer.valueOf(endDate.substring(5, 7)), "yyyyMMdd");
        }else if("year".equals(dateType)){
            start = startDate;
            end = endDate;
        }
        dateMap.put("startDate", start);
        dateMap.put("endDate", end);
        return dateMap;
    }



    /**
     * 获取日期的年份。失败返回0。
     * @param date 日期
     * @return 年份
     */
    public static int getYear(Date date) {
        return getInteger(date, Calendar.YEAR);
    }



    /**
     * 获取日期的月份。失败返回0。
     * @param date 日期
     * @return 月份  必须+1
     */
    public static int getMonth(Date date) {
        return getInteger(date, Calendar.MONTH)+1;
    }



    /**
     * 获取日期的天数。失败返回0。
     * @param date 日期
     * @return 天
     */
    public static int getDay(Date date) {
        return getInteger(date, Calendar.DATE);
    }



    /**
     * 获取日期的小时。失败返回0。
     * @param date 日期
     * @return 小时
     */
    public static int getHour(Date date) {
        return getInteger(date, Calendar.HOUR_OF_DAY);
    }


    /**
     * 获取日期的分钟。失败返回0。
     * @param date 日期
     * @return 分钟
     */
    public static int getMinute(Date date) {
        return getInteger(date, Calendar.MINUTE);
    }


    /**
     * 获取日期的秒钟。失败返回0。
     * @param date 日期
     * @return 秒钟
     */
    public static int getSecond(Date date) {
        return getInteger(date, Calendar.SECOND);
    }

    /**
     * 获取日期中的某数值。如获取月份
     * @param date 日期
     * @param dateType 日期格式
     * @return 数值
     */
    private static int getInteger(Date date, int dateType) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(dateType);
    }


    /**
     * 获得默认的 date pattern
     */
    public static String getDatePattern()
    {
        return FORMAT_04;
    }

    /**
     * 返回当前格式化的日期
     *
     * @Title: getToday
     * @author: luo bin
     * @date 2016年10月12日 上午10:43:38
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:43:38
     * @return
     * @throws
     */
    public static String getToday()
    {
        Date today = new Date();
        return format(today);
    }
    /**
     * 返回当前格式化的时间
     *
     * @Title: getDateTime
     * @author: luo bin
     * @date 2016年10月12日 上午10:44:14
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:44:14
     * @return
     * @throws
     */
    public static String getDateTime()
    {
        Date today = new Date();
        return format(today);
    }

    /**
     * 将日期按照默认格式转换成时间
     *
     * @Title: format
     * @author: luo bin
     * @date 2016年10月12日 上午10:44:39
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:44:39
     * @param date
     * @return
     * @throws
     */
    public static String format(Date date)
    {
        return date == null ? " " : format(date, getDatePattern());
    }

    /**
     * 将日期按照指定格式转换成时间
     *
     * @Title: format
     * @author: luo bin
     * @date 2016年10月12日 上午10:44:39
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:44:39
     * @param date
     * @return
     * @throws
     */
    public static String format(Date date, String pattern)
    {
        return date == null ? " " : new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 将字符串按照默认格式转换成时间
     *
     * @Title: parse
     * @author: luo bin
     * @date 2016年10月12日 上午10:45:30
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:45:30
     * @param strDate
     * @return
     * @throws ParseException
     * @throws
     */
    public static Date parse(String strDate) throws ParseException
    {
        return StringUtils.isEmpty(strDate) ? null : parse(strDate,
                getDatePattern());
    }

    /**
     * 将字符串按照指定格式转换成时间
     *
     * @Title: parse
     * @author: luo bin
     * @date 2016年10月12日 上午10:45:30
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:45:30
     * @param strDate
     * @return
     * @throws ParseException
     * @throws
     */
    public static Date parse(String strDate, String pattern)
            throws ParseException
    {
        return StringUtils.isEmpty(strDate) ? null : new SimpleDateFormat(
                pattern).parse(strDate);
    }

    /**
     * 月数加减
     *
     * @Title: addMonth
     * @author: luo bin
     * @date 2016年10月12日 上午10:46:11
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:46:11
     * @param date
     * @param n
     * @return
     * @throws
     */
    public static Date addMonth(Date date, int n)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, n);
        return cal.getTime();
    }

    /**
     * 日期加减
     *
     * @Title: addDay
     * @author: luo bin
     * @date 2016年10月12日 上午10:49:14
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:49:14
     * @param date
     * @param n
     * @return
     * @throws
     */
    public static Date addDay(Date date,int n){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, n);
        return cal.getTime();
    }

    /**
     * 年份加减
     *
     * @Title: addDay
     * @author: luo bin
     * @date 2016年10月12日 上午10:49:14
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:49:14
     * @param date
     * @param n
     * @return
     * @throws
     */
    public static Date addYear(Date date,int n){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, n);
        return cal.getTime();
    }

    public static String getLastDayOfMonth(String year, String month)
    {
        Calendar cal = Calendar.getInstance();
        // 年
        cal.set(Calendar.YEAR, Integer.parseInt(year));
        // 月，因为Calendar里的月是从0开始，所以要-1
        // cal.set(Calendar.MONTH, Integer.parseInt(month) - 1);
        // 日，设为一号
        cal.set(Calendar.DATE, 1);
        // 月份加一，得到下个月的一号
        cal.add(Calendar.MONTH, 1);
        // 下一个月减一为本月最后一天
        cal.add(Calendar.DATE, -1);
        return String.valueOf(cal.get(Calendar.DAY_OF_MONTH));// 获得月末是几号
    }

    /**
     * 根据年月日获取时间
     *
     * @Title: getDate
     * @author: luo bin
     * @date 2016年10月12日 上午10:51:24
     * @最后修改人: luo bin
     * @最后修改时间：2016年10月12日 上午10:51:24
     * @param year
     * @param month
     * @param day
     * @return
     * @throws ParseException
     * @throws
     */
    public static Date getDate(String year, String month, String day)
            throws ParseException
    {
        String result = year + "- "
                + (month.length() == 1 ? ("0 " + month) : month) + "- "
                + (day.length() == 1 ? ("0 " + day) : day);
        return parse(result);
    }
    /**
     * 取得当前日期
     *
     * @return
     */
    public static Timestamp getNow() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     */
    public static String getDate() {
        return getDate(DEF_FORMAT);
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    public static String getDate(Date date,String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * 获取7天前的日期(一周)
     */
    public static String getPre7Date() {
        Calendar c = Calendar.getInstance();
        //过去七天
        c.setTime(new Date());
        c.add(Calendar.DATE, -7);
        Date d = c.getTime();
        return DateFormatUtils.format(d, DEF_FORMAT);
    }

    /**
     * 向前推算时间,年向前推2年，月份向前推5月
     * @throws ParseException
     */
    public static String getPreDate(String dateType,String startDate,String endDate) {
        if(DATE_MONTH.equals(dateType)){
            try {
                Calendar cs = Calendar.getInstance();
                Calendar ce = Calendar.getInstance();
                Date start = parse(startDate, "yyyy-MM");
                Date end = parse(endDate, "yyyy-MM");
                cs.setTime(start);
                ce.setTime(end);
                ce.add(Calendar.MONTH, -5);
                if(ce.compareTo(cs)<0){
                    return DateFormatUtils.format(ce.getTime(), "yyyy-MM");
                }else{
                    return DateFormatUtils.format(cs.getTime(), "yyyy-MM");
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return startDate;
            }
        }else if(DATE_YEAR.equals(dateType)){
            int start = Integer.valueOf(startDate);
            int end = Integer.valueOf(endDate);
            if(end-start < 2){
                return String.valueOf(end-2);
            }else{
                return startDate;
            }
        }else if(DATE_DAY.equals(dateType)){
            try {
                Calendar cs = Calendar.getInstance();
                Calendar ce = Calendar.getInstance();
                Calendar cm = Calendar.getInstance();
                Date start = parse(startDate, "yyyy-MM-dd");
                Date end = parse(endDate, "yyyy-MM-dd");
                cs.setTime(end);
                ce.setTime(end);
                cm.setTime(start);
                cs.add(Calendar.DAY_OF_YEAR, -29);
                ce.add(Calendar.DAY_OF_YEAR, -9);

                if(cm.compareTo(cs)<0){
                    return DateFormatUtils.format(cs.getTime(), "yyyy-MM-dd");
                }else if(cm.compareTo(ce)>0){
                    return DateFormatUtils.format(ce.getTime(), "yyyy-MM-dd");
                }else{
                    return DateFormatUtils.format(cm.getTime(), "yyyy-MM-dd");
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return startDate;
            }
        }else{
            if(startDate.compareTo(endDate)<=0){
                return startDate;
            }else{
                return endDate;
            }
        }
    }

    /**
     * 获取连续的年份或 月份
     */
    public static List<String> getDateList(String dateType,String startDate,String endDate) {
        List<String> dateList = new ArrayList<String>();
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        if(DATE_MONTH.equals(dateType)){
            try {
                c1.setTime(parse(startDate, "yyyy-MM"));
                c2.setTime(parse(endDate, "yyyy-MM"));
                while(c1.compareTo(c2)<0){
                    dateList.add(DateUtils.getDate(c1.getTime(), "yyyy-MM"));
                    c1.add(Calendar.MONTH, 1);
                }
                dateList.add(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else if(DATE_YEAR.equals(dateType)){
            try {
                c1.setTime(DateUtils.parse(startDate, "yyyy"));
                c2.setTime(DateUtils.parse(endDate, "yyyy"));
                while(c1.compareTo(c2)<0){
                    dateList.add(DateUtils.getDate(c1.getTime(), "yyyy"));
                    c1.add(Calendar.YEAR, 1);
                }
                dateList.add(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else if(DATE_DAY.equals(dateType)){
            try {
                c1.setTime(DateUtils.parse(startDate, "yyyy-MM-dd"));
                c2.setTime(DateUtils.parse(endDate, "yyyy-MM-dd"));
                while(c1.compareTo(c2)<0){
                    dateList.add(DateUtils.getDate(c1.getTime(), "yyyy-MM-dd"));
                    c1.add(Calendar.DAY_OF_YEAR, 1);
                }
                dateList.add(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else{ //季度
            Integer sYear = Integer.valueOf(startDate.substring(0, 4));
            Integer squ = Integer.valueOf(startDate.substring(5, 6));
            Integer eYear = Integer.valueOf(endDate.substring(0, 4));

            while (sYear<=eYear) {
                while(squ<=4){
                    StringBuilder temp = new StringBuilder();
                    temp.append(sYear);
                    temp.append("/");
                    temp.append(squ);
                    if(temp.toString().compareTo(endDate)<=0){
                        dateList.add(temp.toString());
                    }
                    squ++;
                }
                sYear++;
                squ = 1;
            }
        }
        return dateList;
    }

    /**
     * 获取连续的年份或 月份--格式为月份
     */
    public static List<String> getDateMonth(String dateType,String startDate,String endDate) {
        List<String> dateList = new ArrayList<String>();
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        if(DATE_MONTH.equals(dateType)){
            try {
                c1.setTime(parse(startDate, "yyyy-MM"));
                c2.setTime(parse(endDate, "yyyy-MM"));
                while(c1.compareTo(c2)<0){
                    dateList.add(DateUtils.getDate(c1.getTime(), "MM"+"月"));
                    c1.add(Calendar.MONTH, 1);
                }
                dateList.add(endDate.substring(5,7)+"月");
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else{
            try {
                c1.setTime(DateUtils.parse(startDate, "yyyy"));
                c2.setTime(DateUtils.parse(endDate, "yyyy"));
                while(c1.compareTo(c2)<0){
                    dateList.add(DateUtils.getDate(c1.getTime(), "yyyy"));
                    c1.add(Calendar.YEAR, 1);
                }
                dateList.add(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return dateList;
    }

    /**
     *
     * 返回当前年份下当前几个月份，比如：2017-04 返回 [01,02,03,04]
     *
     * @Title: getMonthList
     * @author: luo bin
     * @date 2017年4月13日 下午2:16:03
     * @最后修改人: luo bin
     * @最后修改时间：2017年4月13日 下午2:16:03
     * @param dateType 时间类型
     * @param year 年
     * @param month 月
     * @return 返回list<String> 本年度的月份
     * @throws
     */
    public static List<String> getMonthList(String dateType,String year,String month){
        int count =12;
        List<String> monthList= new ArrayList<String>();
        if(DATE_YEAR.equals(dateType)){
            if(String.valueOf(DateUtils.getYear(new Date())).equals(year)){
                count= DateUtils.getMonth(new Date());
            }
        }else if(DATE_MONTH.equals(dateType)){
            count = Integer.parseInt(month);
        }
        for(int i=1;i<=count;i++){
            monthList.add(i>=10?String.valueOf(i):("0"+i));
        }
        return monthList;
    }

    /**
     *
     * 返回当前年份的前几年，比如：2017 返回 [2014,2015,2016,2017]
     *
     */
    public static List<String> getYearList(String year){
        List<String> list = new ArrayList<String>();
        list.add(String.valueOf(Integer.parseInt(year)-3));
        list.add(String.valueOf(Integer.parseInt(year)-2));
        list.add(String.valueOf(Integer.parseInt(year)-1));
        list.add(String.valueOf(Integer.parseInt(year)));

        return list;
    }

    /**
     * 放回当前年份1月份到month的月份列表[2017-01,2017-02,2017-03]
     * @param dateType
     * @param year
     * @param month
     * @return
     */
    public static List<String> getYearMonthList(String dateType,String year,String month){
        int count =12;
        List<String> monthList= new ArrayList<String>();
        if(DATE_YEAR.equals(dateType)){
            if(String.valueOf(DateUtils.getYear(new Date())).equals(year)){
                count= DateUtils.getMonth(new Date());
            }
        }else if(DATE_MONTH.equals(dateType)){
            count = Integer.parseInt(month);
        }
        for(int i=1;i<=count;i++){
            String value = i>=10?year+"-"+String.valueOf(i):(year+"-"+"0"+i);
            monthList.add(value);
        }
        return monthList;
    }

    /**
     * 放回当前年份1月份到month的月份列表{2017-01:01,2017-02:02,2017-03:03}
     * @param dateType
     * @param year
     * @param month
     * @return
     */
    public static Map<String,String> getYearMonthMap(String dateType,String year,String month){
        Map<String,String> monthMap = new LinkedHashMap<String, String>();
        int count =12;
        if(DATE_YEAR.equals(dateType)){
            if(String.valueOf(DateUtils.getYear(new Date())).equals(year)){
                count= DateUtils.getMonth(new Date());
            }
        }else if(DATE_MONTH.equals(dateType)){
            count = Integer.parseInt(month);
        }
        for(int i=1;i<=count;i++){

            String value = i>=10?String.valueOf(i):("0"+i);
            monthMap.put(year+"-"+value, value);
        }
        return monthMap;
    }

    /**
     * 获取本月最后一天
     * @Title: getDateLastDay
     * @Description: 获取本月最后一天
     * @author: Ouyang
     * @date 2018年11月27日 下午4:00:20
     * @最后修改人: Ouyang
     * @最后修改时间：2018年11月27日 下午4:00:20
     * @param year
     * @param month
     * @return
     * @throws
     */
    public static String getDateLastDay(String year, String month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, Integer.parseInt(year));
        calendar.set(Calendar.MONTH, Integer.parseInt(month)-1);

        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(calendar.getTime());
    }

    public static String getFirstDay(String type, String dateStr) throws ParseException {
        if("27".equals(type)){//时间参数日
            return dateStr;
        }else if("9".equals(type)){//时间参数月
            return dateStr+"-01";
        }else if("10".equals(type)){//年
            return dateStr+"-01-01";
        }else if("26".equals(type)){//季度
            String qu = dateStr.substring(5, 6);
            if("1".equals(qu)){
                return dateStr.substring(0, 4) + "-01-01";
            }else if("2".equals(qu)){
                return dateStr.substring(0, 4) + "-04-01";
            }else if("3".equals(qu)){
                return dateStr.substring(0, 4) + "-07-01";
            }else if("4".equals(qu)){
                return dateStr.substring(0, 4) + "-10-01";
            }else{
                return "";
            }
        }else{
            return "";
        }
    }

    public static String getLastDay(String type, String dateStr) throws ParseException {
        if("27".equals(type)){//时间参数日
            return dateStr;
        }else if("9".equals(type)){//时间参数月
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, Integer.parseInt(dateStr.substring(0, 4)));
            calendar.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(5, 7))-1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
            return DateUtils.format(calendar.getTime(), "yyyy-MM-dd");
        }else if("10".equals(type)){//年
            return dateStr+"-12-31";
        }else if("26".equals(type)){//季度
            String qu = dateStr.substring(5, 6);
            if("1".equals(qu)){
                return dateStr.substring(0, 4) + "-03-31";
            }else if("2".equals(qu)){
                return dateStr.substring(0, 4) + "-06-30";
            }else if("3".equals(qu)){
                return dateStr.substring(0, 4) + "-09-30";
            }else if("4".equals(qu)){
                return dateStr.substring(0, 4) + "-12-31";
            }else{
                return "";
            }
        }else{
            return "";
        }
    }

    /**
     * 获取本月最后一天
     * @Title: getDateLastDay
     * @Description: 获取本月最后一天
     * @author: Ouyang
     * @date 2018年11月27日 下午4:00:20
     * @最后修改人: Ouyang
     * @最后修改时间：2018年11月27日 下午4:00:20
     * @param year
     * @param month
     * @return
     * @throws
     */
    public static String getDateLastDay(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month-1);

        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd ");
        return format.format(calendar.getTime());
    }

    /**
     *
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
     *
     * @param date
     * @return
     */
    public static String getSeason(Date date) {
        int season = 0;
        int year = getYear(date);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return year+"/"+season;
    }

    /**
     *
     * @Title: getSeason
     * @Description:
     * @author: Ouyang
     * @date 2018年11月27日 下午4:43:57
     * @最后修改人: Ouyang
     * @最后修改时间：2018年11月27日 下午4:43:57
     * @param dateStr
     * @param pattern
     * @return
     * @throws
     */
    public static String getSeason(String dateStr,String pattern) {
        Date date=null;
        try {
            date = parse(dateStr, pattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return getSeason(date);
    }

    /**
     * UTCToCST(dateUTC,"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
     * UTC时间转北京时间
     * @param UTCStr
     * @param format
     * @return
     */
    public static Date UTCToCST(String UTCStr, String format) {
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            date = sdf.parse(UTCStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
//        System.out.println("UTC时间: " + date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
        //calendar.getTime() 返回的是Date类型，也可以使用calendar.getTimeInMillis()获取时间戳
//        System.out.println("北京时间: " + calendar.getTime());
        return calendar.getTime();
    }


    /**
     * 本地时间转UTC
     * @param localDate
     * @param format
     */
    public static String localToUTC(String  localDate,String format){
        SimpleDateFormat sdf= new SimpleDateFormat(format);
        Date date = null;
        try {
            date = sdf.parse(localDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int zoneOffset = calendar.get(Calendar.ZONE_OFFSET);
        int dstOffset = calendar.get(Calendar.DST_OFFSET);
        calendar.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        long timeInMillis = calendar.getTimeInMillis();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        return df.format(timeInMillis);
    }

    /**
     * 将日期格式转换成String
     * @author chenssy
     * @date Dec 31, 2013
     *
     * @param value 需要转换的日期
     * @param format 日期格式
     * @return String
     */
    public static String dateToString(Date value,String format){
        if(value == null){
            return null;
        }
        if(format == null || "".equals(format)){
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(value);
    }
    /**
     * 获取一年起始时间
     * @param date
     * @return
     */
    public static Date getFirstDay_Year(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, firstDay);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    public static String getFirstDay_Year(Date date,String pattern) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, firstDay);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date datNew = cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(datNew);
    }
    /**
     * 获取一年结束时间
     * @param date
     * @return
     */
    public static Date getFinalyDay_Year(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int finalDat = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, finalDat);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    public static String getFinalyDay_Year(Date date,String pattern) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int finalDat = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, finalDat);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        Date datNew = cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(datNew);
    }

    public static String getFirstDay_Month(String date,String pattern,String pattern2) {
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(new SimpleDateFormat(pattern).parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int firstDat = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, firstDat);
        cal.set(Calendar.HOUR_OF_DAY, 00);
        cal.set(Calendar.MINUTE, 00);
        cal.set(Calendar.SECOND, 00);
        return new SimpleDateFormat(pattern2).format(cal.getTime());
    }
    public static String getFinalyDay_Month(String date,String pattern,String pattern2) {
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(new SimpleDateFormat(pattern).parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int finalDat = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, finalDat);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return new SimpleDateFormat(pattern2).format(cal.getTime());
    }

    /**
     * 获取时间区间
     *
     * @param d1 开始时间区间
     * @param d2 结束时间区间
     * @return 时间区间集合
     */
    public static List<String> getTimeList(String d1, String d2, String pattern, String type) {
        SimpleDateFormat sd = new SimpleDateFormat(pattern);
        Calendar c = Calendar.getInstance();
        List<String> list = new ArrayList<String>();
        Date st, et;
        long sl, el, length;
        try {
            st = sd.parse(d1);
            et = sd.parse(d2);
            sl = st.getTime();
            el = et.getTime();
            if (type == "hour") {// 以小时为间隔
                length = (el - sl) / (60 * 60 * 1000);
            } else if (type == "day") {// 一天为间隔
                length = (el - sl) / (24 * 60 * 60 * 1000);
            } else {// 一月为间隔
                /**当时间段过长时，会产生误差，因为存在闰年平年**/
                String d1Int = d1.substring(5).startsWith("0")?d1.substring(6, 7):d1.substring(5,7);
                String d2Int = d2.substring(5).startsWith("0")?d1.substring(6, 7):d2.substring(5,7);
                if (Integer.parseInt(d1Int) <= 2 && Integer.parseInt(d2Int) >=2 ) {
                    length = (el - sl) / (29L * 24L * 60L * 60L * 1000L);//含有二月份的执行
                }else {
                    length = (el - sl) / (30L * 24L * 60L * 60L * 1000L); //必须加L，否则溢出结果为负数
                }
            }
            list.add(sd.format(st));
            for (int i = 0; i < length; i++) {
                c.setTime(st);
                if (type == "hour") {
                    c.add(Calendar.HOUR, 1);
                    st = c.getTime();
                } else if (type == "day") {
                    c.add(Calendar.DAY_OF_YEAR, 1);
                    st = c.getTime();
                } else {
                    c.add(Calendar.MONTH, 1);
                    st = c.getTime();
                }
                list.add(sd.format(st));
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * @Title: getWeek
     * @Description: 根据日期字符串判断是当月第几周
     * @param str
     * @return
     * @throws Exception    参数
     * @return int    返回类型
     * @throws
     */
    public static int getMonthWeek(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 第几周
        int week = calendar.get(Calendar.WEEK_OF_MONTH);
        // 第几天，从周日开始
        // int day = calendar.get(Calendar.DAY_OF_WEEK);
        return week;
    }

    //得到开始结束年份之间的所有年份
    public static List<String> getTimeYear(String start,String end){
        int startTime = Integer.valueOf(start);
        int endTime = Integer.valueOf(end);
        List<String> time = new ArrayList<String>();
        if (startTime <= endTime) {
            while(startTime != endTime) {
                time.add(startTime+"");
                startTime ++;
            }
            time.add(endTime+"");
        }
        return time;
    }

    //获取当前系统时间
    public static Date getSystemTime(){
        Date enabledTimeDate = new Date();

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            enabledTimeDate= sdf.parse(sdf.format(new Date()));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return enabledTimeDate;
    }

    public static Date getSystemTime(String pattern){
        Date enabledTimeDate = new Date();

        SimpleDateFormat sdf=new SimpleDateFormat(pattern);
        try {
            enabledTimeDate= sdf.parse(sdf.format(new Date()));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return enabledTimeDate;
    }

    /**
     * @Title: getDaysByYearMonth
     * @Description: 获取月份的天数
     * @param year
     * @param month
     * @return    参数
     * @return int    返回类型
     * @throws
     */
    public static int getDaysByYearMonth(int year, int month) {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    // 计算两个时间的相差天数
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) { // 同一年
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) { // 闰年
                    timeDistance += 366;
                } else { // 不是闰年
                    timeDistance += 365;
                }
            }
            return timeDistance + (day2 - day1);
        } else { // 不同年
            return day2 - day1 + 1;
        }
    }

    // 根据年份与周数计算周的开始与结束时间
    public static Map<String, String> weekStartEndTime(int year, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, 0, 1);
        int dayOfWeek = 7 - calendar.get(Calendar.DAY_OF_WEEK) + 1; // 算出第一周还剩几天 +1是因为1号是1天
        week = week - 2; // 周数减去第一周再减去要得到的周
        calendar.add(Calendar.DAY_OF_YEAR, week * 7 + dayOfWeek);
        String startTime = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
        calendar.add(Calendar.DAY_OF_YEAR, 6);
        String endTime = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
        Map<String, String> map = new HashMap<String, String>();
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        return map;
    }

    /**
     * @Title: getWeek
     * @Description: 根据日期字符串输出中间的周数
     * @return
     * @throws Exception    参数
     * @return yyyy年第MM周    返回类型List
     * @throws
     */
    public static List<String> getYearWeek(String start,String end) {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        List<String> list = new ArrayList<String>();
        //List<String> list = new ArrayList<String>();
        Date st, et;
        long sl, el, length;
        try {
            st = sd.parse(start);
            et = sd.parse(end);
            sl = st.getTime();
            el = et.getTime();
            length = (el - sl) / (24 * 60 * 60 * 1000);
            c.setTime(st);
            int year1 = c.get(Calendar.YEAR);
            int week1 = c.get(Calendar.WEEK_OF_YEAR);
            String msg1 = year1 + "年第" + week1 + "周";
            list.add(msg1);
            for (int i = 0; i < length; i++) {
                c.add(Calendar.DAY_OF_YEAR, 1);
                st = c.getTime();
                c.setTime(st);
                int year = c.get(Calendar.YEAR);
                int week = c.get(Calendar.WEEK_OF_YEAR);
                String msg = year + "年第" + week + "周";
                list.add(msg);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        list = list.stream().distinct().collect(Collectors.toList());
        return list;
    }

    /**
     * @Title: getWeek
     * @Description: 根据日期字符串判断是当月第几周
     * @param str
     * @return
     * @throws Exception    参数
     * @return yyyy年第x周    返回类型
     * @throws
     */
    public static String getMonthWeekString(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 第几周
        int year = calendar.get(Calendar.YEAR);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        String msg = year + "年第" + week + "周";
        // 第几天，从周日开始
        // int day = calendar.get(Calendar.DAY_OF_WEEK);
        return msg;
    }

    public static String getYearString(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        return year + "";
    }

    public static String getWeekString(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 第几周
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        return week + "";
    }

    /**
     * @Title: getWeek
     * @Description: 根据日期字符串判断是当月第几周
     * @param str
     * @return
     * @throws Exception    参数
     * @return yyyy年第x周    返回类型
     * @throws
     */
    public static String getMonthWeekStringUSA(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
//		calendar.setFirstDayOfWeek(Calendar.SUNDAY);
        calendar.setMinimalDaysInFirstWeek(7);
        calendar.setTime(date);
        // 第几周
        int year = calendar.get(Calendar.YEAR);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        String msg = year + "年第" + week + "周";
        // 第几天，从周日开始
        // int day = calendar.get(Calendar.DAY_OF_WEEK);
        return msg;
    }

    public static String getQuarter(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        String quarter = null;
        switch (calendar.get(Calendar.MONTH)) {
            case 1:
            case 2:
            case 3:
                quarter = "1";
                break;
            case 4:
            case 5:
            case 6:
                quarter = "2";
                break;
            case 7:
            case 8:
            case 9:
                quarter = "3";
                break;
            case 10:
            case 11:
            case 12:
                quarter = "4";
                break;
        }
        return quarter;
    }

    /**
     * 获取两个日期字符串之间的所有年份/月份/天/小时（左闭右闭）
     * 如果dataUnit未HOUR时 startDateStr，endDateStr的格式需和pattern一致
     * @param startDateStr  yyyy-MM-dd
     * @param endDateStr    yyyy-MM-dd
     * @param dateUnit
     * @param pattern yyyy-MM-dd yyyy-MM-dd:HH
     * @return
     */
    public static List<String> getDateStrBetween(String startDateStr, String endDateStr, DateUnit dateUnit, String pattern) {
        List<String> result = new ArrayList<>();
        SimpleDateFormat sdf;
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();

        try {
            sdf = new SimpleDateFormat(pattern);
            start.setTime(sdf.parse(startDateStr));
            end.setTime(sdf.parse(endDateStr));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Calendar curr = start;

        switch (dateUnit) {
            case YEAR:
                sdf = new SimpleDateFormat(pattern);
                while (curr.before(end)) {
                    result.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.YEAR, 1);
                }
                break;
            case MONTH:
                sdf = new SimpleDateFormat(pattern);
                while (curr.before(end)) {
                    result.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.MONTH, 1);
                }
                break;
            case DAY:
                sdf = new SimpleDateFormat(pattern);
                while (curr.before(end)) {
                    result.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.DAY_OF_MONTH, 1);
                }
                break;
            case HOUR:
                sdf = new SimpleDateFormat(pattern);
                while (curr.before(end)) {
                    result.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.HOUR, 1);
                }
                break;
            default:
                sdf = new SimpleDateFormat(FORMAT_05);
                while (curr.before(end)) {
                    result.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.YEAR, 1);
                }
                break;
        }

        // 最后要加上 endDateStr 所属的年份/月份/天（保证不漏）
        result.add(sdf.format(end.getTime()));
        return result.stream().distinct().collect(Collectors.toList());
    }

    public static void main(String[] args) {
//		List<String> list = getDateStrBetween("2021-01-01", "2021-02-01", DateUnit.MONTH, "yyyy-MM");
//        List<String> list = getDateStrBetween("2021-01-01 00:00:00", "2021-01-02 12:00:00", DateUnit.HOUR, "yyyy-MM-dd HH");
        List<String> list = getDateStrBetween("2023-02-24", "2023-03-26", DateUnit.DAY, "yyyy-MM-dd");
        for (String y : list){
            System.out.println(y);
        }
    }
}
